﻿using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using Core.Utilities;


namespace Core
{
    public class GridViewUtil
    {
        /// <summary>
        /// Groupings the grid view.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="cellColumnNo">The cell column no.</param>
        public static void GroupingGridView(GridView gv, params int[] cellColumnNo)
        {
            string text = "";
            int count = 0;
            Hashtable ht = new Hashtable();

            // loop through all rows to get row counts
            foreach (GridViewRow gvr in gv.Rows)
            {
                if (gvr.RowType == DataControlRowType.DataRow)
                {
                    string sumName = "";
                    for (int i = 0; i < cellColumnNo.Length; i++)
                    {
                        sumName += gvr.Cells[cellColumnNo[i]].Text;
                    }

                    if (sumName == text)
                    {
                        count++;
                    }
                    else
                    {
                        if (count > 0)
                        {
                            ht.Add(text, count);
                        }


                        text = sumName;
                        count = 1;
                    }
                }
            }

            if (count > 1)
            {
                ht.Add(text, count);
            }


            // loop through all rows again to set rowspan
            text = "";
            foreach (GridViewRow gvr in gv.Rows)
            {
                if (gvr.RowType == DataControlRowType.DataRow)
                {
                    string sumName = "";
                    for (int i = 0; i < cellColumnNo.Length; i++)
                    {
                        sumName += gvr.Cells[cellColumnNo[i]].Text;
                    }

                    if (sumName == text)
                    {
                        //for (int i = 0; i < cellColumnNo.Length; i++)
                        //{

                        //    //gvr.Cells.Remove(gvr.Cells[0]);
                        //    gvr.Cells.Remove(gvr.Cells[cellColumnNo[0]]);
                        //}
                        for (int i = cellColumnNo.Length - 1; i >= 0; i--)
                        {

                            //gvr.Cells.Remove(gvr.Cells[0]);
                            gvr.Cells.Remove(gvr.Cells[cellColumnNo[i]]);
                        }

                    }
                    else
                    {
                        for (int i = 0; i < cellColumnNo.Length; i++)
                        {
                            text = sumName;
                            gvr.Cells[cellColumnNo[i]].RowSpan = Convert.ToInt32(ht[text]);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Groupings the grid view.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="columnIndex">Index of the column.</param>
        /// <example>Call GridViewUtil.GroupingGridView((GridView)sender, 1) under Gridview's DataBound event</example>
        public static void GroupingGridView(GridView gv, int columnIndex)
        {
            if (columnIndex >= gv.Columns.Count)
                return;

            TableCell groupStartCell = null;

            for (int i = 0; i < gv.Rows.Count; i++)
            {
                TableCell currentCell = gv.Rows[i].Cells[columnIndex];

                bool isNewGroup = (null == groupStartCell) || (0 != String.CompareOrdinal(currentCell.Text, groupStartCell.Text));

                if (isNewGroup)
                {
                    //if (null != groupStartCell)
                    //{
                    //    GroupingGridView(gv, columnIndex + 1);
                    //}

                    groupStartCell = currentCell;
                    groupStartCell.RowSpan = 1;
                }
                else
                {
                    currentCell.Visible = false;
                    groupStartCell.RowSpan += 1;
                }
            }

            //GroupingGridView(gv, columnIndex + 1);
        }

        /// <summary>
        /// Adds the total row.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="totalTextColumn">The total text column.</param>
        /// <param name="qtyColumn">The qty column.</param>
        /// <param name="decimalPoint">The decimal point.</param>
        /// <example>After bind data call method GridViewUtil.AddTotalRow(gvCalculationList, 1, 3, 2)</example>
        public static void AddTotalRow(GridView grid, int totalTextColumn, int qtyColumn, int decimalPoint)
        {
            decimal total = 0;

            //If row count is zero then return
            if (grid.Rows.Count == 0)
            {
                return;
            }

            // Turn on the footer in the GridView 
            grid.ShowFooter = true;
            grid.FooterRow.Visible = true;

            foreach (GridViewRow gvr in grid.Rows)
            {
                if (gvr.RowType == DataControlRowType.DataRow)
                {
                    // Add the value to the total if it is an Integer
                    decimal qty;

                    if (gvr.Cells[qtyColumn].Controls.Count > 0)
                    {
                        foreach (Control ctl in gvr.Cells[qtyColumn].Controls)
                        {
                            if (ctl is TextBox)
                            {
                                TextBox txtQuantity = (TextBox)ctl;

                                if (decimal.TryParse(txtQuantity.Text, out qty))
                                {
                                    total += qty;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (decimal.TryParse(gvr.Cells[qtyColumn].Text, out qty))
                        {
                            total += qty;
                        }
                    }
                }
            }

            //Display value on footer row
            grid.FooterRow.Cells[totalTextColumn].Text = "Total";
            grid.FooterRow.Cells[qtyColumn].Text = string.Format("{0:#,##0.00}", Math.Round(total, decimalPoint));
            grid.FooterRow.Cells[qtyColumn].Style.Add("text-align", "right");
        }

        /// <summary>
        /// Adds the total row.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="totalTextColumn">The total text column.</param>
        /// <param name="qtyColumnList">The qty column list.</param>
        /// <param name="decimalPoint">The decimal point.</param>
        public static void AddTotalRow(GridView grid, int totalTextColumn, int[] qtyColumnList, int decimalPoint)
        {
            //If row count is zero then return
            if (grid.Rows.Count == 0)
            {
                return;
            }

            // Turn on the footer in the GridView 
            grid.ShowFooter = true;
            grid.FooterRow.Visible = true;

            foreach (int qtyColumn in qtyColumnList)
            {
                decimal total = 0;

                foreach (GridViewRow gvr in grid.Rows)
                {
                    if (gvr.RowType == DataControlRowType.DataRow)
                    {
                        // Add the value to the total if it is an Integer
                        decimal qty;

                        if (gvr.Cells[qtyColumn].Controls.Count > 0)
                        {
                            foreach (Control ctl in gvr.Cells[qtyColumn].Controls)
                            {
                                if (ctl is TextBox)
                                {
                                    TextBox txtQuantity = (TextBox)ctl;

                                    if (decimal.TryParse(txtQuantity.Text, out qty))
                                    {
                                        total += qty;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (decimal.TryParse(gvr.Cells[qtyColumn].Text, out qty))
                            {
                                total += qty;
                            }
                        }
                    }
                }

                //Display value on footer row
                grid.FooterRow.Cells[totalTextColumn].Text = "Total";
                grid.FooterRow.Cells[qtyColumn].Text = string.Format("{0:#,##0.00}", Math.Round(total, decimalPoint));
                grid.FooterRow.Cells[qtyColumn].Style.Add("text-align", "right");
            }
        }

        /// <summary>
        /// Inserts the empty record.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="dt">The dt.</param>
        public static void InsertEmptyRecord(GridView gv, DataTable dt)
        {
            // Remove contraints so an empty row can be added.
            dt.Constraints.Clear();
            foreach (DataColumn dc in dt.Columns)
                dc.AllowDBNull = true;

            // Add a blank row to the dataset
            dt.Columns[0].AllowDBNull = true;
            dt.Rows.Add(dt.NewRow());
            // Bind the DataSet to the GridView
            gv.DataSource = dt;
            gv.DataBind();

            if (gv.ShowFooter)
            {
                gv.Rows[0].Visible = false;
            }
            else
            {
                // Get the number of columns to know what the Column Span should be
                int columnCount = gv.Rows[0].Cells.Count;
                // Call the clear method to clear out any controls that you use in the columns.  I use a dropdown list in one of the column so this was necessary.
                gv.Rows[0].Cells.Clear();
                gv.Rows[0].Cells.Add(new TableCell());
                gv.Rows[0].Cells[0].ColumnSpan = columnCount;
                gv.Rows[0].Cells[0].Text = "No record found.";
            }
        }

        /// <summary>
        /// Inserts the empty record.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="columnList">The column list.</param>
        public static void InsertEmptyRecord(GridView gv, string[] columnList)
        {
            DataTable dt = new DataTable("EmptyTable");
            foreach (string column in columnList)
            {
                dt.Columns.Add(new DataColumn(column));
            }
            dt.Rows.Add(dt.NewRow());

            // Bind the DataSet to the GridView
            gv.DataSource = dt;
            gv.DataBind();

            if (gv.ShowFooter)
            {
                gv.Rows[0].Visible = false;
            }
            else
            {
                // Get the number of columns to know what the Column Span should be
                int columnCount = gv.Rows[0].Cells.Count;
                // Call the clear method to clear out any controls that you use in the columns.  I use a dropdown list in one of the column so this was necessary.
                gv.Rows[0].Cells.Clear();
                gv.Rows[0].Cells.Add(new TableCell());
                gv.Rows[0].Cells[0].ColumnSpan = columnCount;
                gv.Rows[0].Cells[0].Text = "No record found.";
            }
        }

        /// <summary>
        /// Adds the extra footer row.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="text">The text.</param>
        public static void AddExtraFooterRow(GridView gv, string text)
        {
            // Start Add Footer Row
            GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Footer, DataControlRowState.Normal);
            TableCell cell = new TableCell();
            cell.ColumnSpan = gv.Columns.Count;
            cell.HorizontalAlign = HorizontalAlign.Center;
            cell.Text = text;
            row.Cells.Add(cell);

            gv.Controls[0].Controls.Add(row);
            //End Add Footer Row
        }

        /// <summary>
        /// Adds the extra footer row.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="firstEditCellIndex">First index of the edit cell.</param>
        /// <param name="dt">The dt.</param>
        /// <returns></returns>
        public static GridViewRow AddExtraFooterRow(GridView gv, int firstEditCellIndex, DataTable dt)
        {
            GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Footer, DataControlRowState.Normal);
            for (int columnIndex = firstEditCellIndex; columnIndex < gv.Columns.Count; columnIndex++)
            {
                DataRow dr = dt.Rows[0];

                TableCell cell = new TableCell();
                cell.HorizontalAlign = HorizontalAlign.Center;
                cell.Text = dr[columnIndex - firstEditCellIndex].ToString();

                row.Cells.Add(cell);
            }

            return row;
        }

        /// <summary>
        /// Adds the seperate row.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the row.</param>
        /// <param name="intArray">The int array.</param>
        public static void AddSeperateRow(GridView gv, int rowIndex, int[] intArray)
        {
            if (intArray == null)
            {
                return;
            }

            if (ArrayUtil.ValueExistsInArray(rowIndex, intArray))
            {

                // Start Add Seperate Row
                GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
                TableCell cell = new TableCell();
                cell.BackColor = System.Drawing.Color.Red;
                cell.ForeColor = System.Drawing.Color.White;
                cell.ColumnSpan = gv.Columns.Count;
                cell.HorizontalAlign = HorizontalAlign.Center;
                cell.Text = "&nbsp;";
                row.Cells.Add(cell);

                gv.Controls[0].Controls.AddAt(gv.Controls[0].Controls.Count, row);
                //End Add Seperate Row
            }
        }

        /// <summary>
        /// Adds the color of the seperate row with back.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the row.</param>
        /// <param name="intArray">The int array.</param>
        /// <param name="color">The color.</param>
        /// <param name="text">The text.</param>
        /// <param name="minuscolumn">The minuscolumn.</param>
        public static void AddSeperateRowWithBackColor(GridView gv, int rowIndex, int[] intArray, System.Drawing.Color color, string text, int minuscolumn)
        {
            if (intArray == null)
            {
                return;
            }

            if (ArrayUtil.ValueExistsInArray(rowIndex, intArray))
            {

                // Start Add Seperate Row
                GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
                TableCell cell = new TableCell();
                cell.BackColor = color;
                cell.ForeColor = System.Drawing.Color.White;
                // ColumnSpan minus SingleClick Columns
                cell.ColumnSpan = gv.Columns.Count - minuscolumn;
                cell.HorizontalAlign = HorizontalAlign.Center;
                cell.Text = text;
                row.Cells.Add(cell);

                gv.Controls[0].Controls.AddAt(gv.Controls[0].Controls.Count, row);
                //End Add Seperate Row
            }
        }

        /// <summary>
        /// Adds the seperate row.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the row.</param>
        /// <param name="intArray">The int array.</param>
        /// <param name="startColumn">The start column.</param>
        public static void AddSeperateRow(GridView gv, int rowIndex, int[] intArray, int startColumn)
        {
            if (intArray == null)
            {
                return;
            }

            if (ArrayUtil.ValueExistsInArray(rowIndex, intArray))
            {
                // Start Add Seperate Row
                GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);

                //Get Text from previous row
                for (int i = startColumn; i < gv.HeaderRow.Cells.Count - 1; i++)
                {
                    if (rowIndex - 1 >= 0)
                    {
                        string value = gv.Rows[rowIndex - 1].Cells[i].Text;

                        TableCell cell = new TableCell();
                        cell.BackColor = System.Drawing.Color.Red;
                        cell.ForeColor = System.Drawing.Color.White;
                        //cell.ColumnSpan = gv.Columns.Count;
                        cell.HorizontalAlign = HorizontalAlign.Center;
                        cell.Text = value;
                        row.Cells.Add(cell);

                        if (i == gv.HeaderRow.Cells.Count - 2)
                        {
                            //Add Last Column
                            cell = new TableCell();
                            cell.BackColor = System.Drawing.Color.Red;
                            cell.ForeColor = System.Drawing.Color.White;
                            //cell.ColumnSpan = gv.Columns.Count;
                            cell.HorizontalAlign = HorizontalAlign.Center;
                            cell.Text = "Total " + value;
                            row.Cells.Add(cell);
                        }
                    }
                }

                gv.Controls[0].Controls.AddAt(gv.Controls[0].Controls.Count, row);
                //End Add Seperate Row
            }
        }

        /// <summary>
        /// Adds the seperate row for data bound.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the int row.</param>
        /// <param name="arrayGroup">The array group.</param>
        /// <param name="backColor">Color of the back.</param>
        /// <param name="foreColor">Color of the fore.</param>
        /// <param name="firstEditCellIndex">First index of the edit cell.</param>
        /// <param name="labelIndexInCell">The label index in cell.</param>
        /// <param name="isShowSumColum">if set to <c>true</c> [is show sum colum].</param>
        /// <returns></returns>
        public static GridViewRow AddSeperateRowForDataBound(GridView gv, int rowIndex, int[] arrayGroup, System.Drawing.Color backColor, System.Drawing.Color foreColor,
            int firstEditCellIndex, int labelIndexInCell, bool isShowSumColum)
        {
            return AddSeperateRowForDataBound(gv, rowIndex, arrayGroup, backColor, foreColor, firstEditCellIndex, labelIndexInCell, isShowSumColum, false);
        }

        /// <summary>
        /// Adds the seperate row for data bound.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the int row.</param>
        /// <param name="arrayGroup">The array group.</param>
        /// <param name="backColor">Color of the back.</param>
        /// <param name="foreColor">Color of the fore.</param>
        /// <param name="firstEditCellIndex">First index of the edit cell.</param>
        /// <param name="labelIndexInCell">The label index in cell.</param>
        /// <param name="isShowSumColum">if set to <c>true</c> [is show sum colum].</param>
        /// <param name="isRoundDecimal">if set to <c>true</c> [is round decimal].</param>
        /// <returns></returns>
        public static GridViewRow AddSeperateRowForDataBound(GridView gv, int rowIndex, int[] arrayGroup, System.Drawing.Color backColor, System.Drawing.Color foreColor,
            int firstEditCellIndex, int labelIndexInCell, bool isShowSumColum, bool isRoundDecimal)
        {
            int startRowIndex = 0;
            for (int i = 0; i < arrayGroup.Length; i++)
            {
                if (rowIndex <= arrayGroup[i])
                {
                    if ((i - 1) < 0)
                    {
                        startRowIndex = 0;
                        break;
                    }
                    startRowIndex = arrayGroup[i - 1] + 1;
                    break;
                }
            }

            GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
            for (int columnIndex = firstEditCellIndex; columnIndex < gv.Columns.Count; columnIndex++)
            {

                //From Start Row Index to Current Row
                decimal intColumn = 0;
                for (int rowIndexIndex = startRowIndex; rowIndexIndex <= rowIndex; rowIndexIndex++)
                {
                    if (gv.Rows[rowIndexIndex].Cells[columnIndex].Controls.Count > 0)
                    {
                        Label lblQuantity = (Label)gv.Rows[rowIndexIndex].Cells[columnIndex].Controls[labelIndexInCell];
                        {
                            decimal decValue;
                            if (decimal.TryParse(lblQuantity.Text, out decValue))
                            {
                                intColumn += decValue;
                            }
                        }
                    }
                    else
                    {
                        if (isShowSumColum)
                        {
                            decimal decValue;
                            string value = gv.Rows[rowIndexIndex].Cells[columnIndex].Text;
                            if (decimal.TryParse(value, out decValue))
                            {
                                intColumn += decValue;
                            }
                        }
                    }
                }
                //From Start Row Index to Current Row

                TableCell cell = new TableCell();
                cell.BackColor = backColor;
                cell.ForeColor = foreColor;
                //cell.ColumnSpan = gv.Columns.Count;
                cell.HorizontalAlign = HorizontalAlign.Center;

                if (isRoundDecimal)
                {
                    cell.Text = Math.Round(intColumn).ToString();
                }
                else
                {
                    cell.Text = intColumn.ToString();
                }

                row.Cells.Add(cell);
            }

            return row;
        }

        /// <summary>
        /// Adds the seperate row text box for data bound.
        /// </summary>
        /// <param name="gv">The gv.</param>
        /// <param name="rowIndex">Index of the int row.</param>
        /// <param name="arrayGroup">The array group.</param>
        /// <param name="backColor">Color of the back.</param>
        /// <param name="foreColor">Color of the fore.</param>
        /// <param name="firstEditCellIndex">First index of the edit cell.</param>
        /// <param name="textBoxIndexInCell">The text box index in cell.</param>
        /// <param name="isShowSumColum">if set to <c>true</c> [is show sum colum].</param>
        /// <returns></returns>
        public static GridViewRow AddSeperateRowTextBoxForDataBound(GridView gv, int rowIndex, int[] arrayGroup, System.Drawing.Color backColor, System.Drawing.Color foreColor,
    int firstEditCellIndex, int textBoxIndexInCell, bool isShowSumColum)
        {
            int startRowIndex = 0;
            for (int i = 0; i < arrayGroup.Length; i++)
            {
                if (rowIndex <= arrayGroup[i])
                {
                    if ((i - 1) < 0)
                    {
                        startRowIndex = 0;
                        break;
                    }
                    startRowIndex = arrayGroup[i - 1] + 1;
                    break;
                }
            }

            GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
            for (int columnIndex = firstEditCellIndex; columnIndex < gv.Columns.Count; columnIndex++)
            {

                //From Start Row Index to Current Row
                decimal intColumn = 0;
                for (int rowIndexIndex = startRowIndex; rowIndexIndex <= rowIndex; rowIndexIndex++)
                {
                    if (gv.Rows[rowIndexIndex].Cells[columnIndex].Controls.Count > 0)
                    {
                        TextBox lblQuantity = (TextBox)gv.Rows[rowIndexIndex].Cells[columnIndex].Controls[textBoxIndexInCell];
                        {
                            decimal decValue;
                            if (decimal.TryParse(lblQuantity.Text, out decValue))
                            {
                                intColumn += decValue;
                            }
                        }
                    }
                    else
                    {
                        if (isShowSumColum)
                        {
                            decimal decValue;
                            string value = gv.Rows[rowIndexIndex].Cells[columnIndex].Text;
                            if (decimal.TryParse(value, out decValue))
                            {
                                intColumn += decValue;
                            }
                        }
                    }
                }
                //From Start Row Index to Current Row

                TableCell cell = new TableCell();
                cell.BackColor = backColor;
                cell.ForeColor = foreColor;
                //cell.ColumnSpan = gv.Columns.Count;
                cell.HorizontalAlign = HorizontalAlign.Center;
                cell.Text = intColumn.ToString();
                row.Cells.Add(cell);
            }

            return row;
        }

        /// <summary>
        /// Sets the grid view on mouse over.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param>
        public static void SetGridViewOnMouseOver(object sender, GridViewRowEventArgs e)
        {
            SetGridViewOnMouseOver(sender, e, System.Drawing.Color.Red);
        }

        /// <summary>
        /// Sets the grid view on mouse over.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param>
        /// <param name="ignorColor">Color of the ignor.</param>
        public static void SetGridViewOnMouseOver(object sender, GridViewRowEventArgs e, System.Drawing.Color ignorColor)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                if (e.Row.BackColor != ignorColor)
                {
                    e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='Silver'");

                    if (e.Row.RowState == DataControlRowState.Normal)
                    {
                        e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#F7F6F3'");
                    }
                    else
                    {
                        e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='White'");
                    }
                }
            }
        }

        /// <summary>
        /// Gets the total page.
        /// </summary>
        /// <param name="totalRow">The i total row.</param>
        /// <param name="pageSize">Size of the i page.</param>
        /// <returns></returns>
        public static int GetTotalPage(int totalRow, int pageSize)
        {
            int totalPage = totalRow / pageSize;
            if ((totalRow % pageSize) > 0)
            {
                totalPage += 1;
            }

            return totalPage;
        }

        /// <summary>
        /// Gets the grid view row from row command.
        /// </summary>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewCommandEventArgs"/> instance containing the event data.</param>
        /// <returns></returns>
        public static GridViewRow GetGridViewRowFromRowCommand(GridViewCommandEventArgs e)
        {
            return (GridViewRow)((Control)e.CommandSource).NamingContainer;
        }

        /// <summary>
        /// Gets the grid view row from drop down list.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <returns></returns>
        public static GridViewRow GetGridViewRowFromDropDownList(object sender)
        {
            return (GridViewRow)(((Control)sender).NamingContainer);
        }
    }
}
